package com.github.webshell.handler;

import com.github.webshell.service.TioWebShellService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.tio.core.ChannelContext;
import org.tio.core.Tio;
import org.tio.http.common.HttpRequest;
import org.tio.http.common.HttpResponse;
import org.tio.websocket.common.WsRequest;
import org.tio.websocket.common.WsSessionContext;
import org.tio.websocket.server.handler.IWsMsgHandler;

import java.nio.ByteBuffer;
import java.util.Objects;
import java.util.UUID;

/**
 * @ClassName: ImWsHandler
 * @Description: ImWsHandler
 * @Author: finder
 * @Date: 2020/7/24 15:23
 **/
public class WebSocketWsHandler implements IWsMsgHandler {

    private static Logger log = LoggerFactory.getLogger(WebSocketWsHandler.class);
    public static final WebSocketWsHandler me = new WebSocketWsHandler();

    public WebSocketWsHandler() {

    }

    /**
     * 握手时走这个方法，业务可以在这里获取cookie，request参数等
     */
    @Override
    public HttpResponse handshake(HttpRequest request, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
        String clientip = request.getClientIp();
        String uuid = clientip + "id:" + UUID.randomUUID().toString().replace("-","");
        Tio.bindBsId(channelContext,uuid);
        log.info("收到来自:{}\t的ws握手包:{}" , clientip , request.toString());
        TioWebShellService service = TioWebShellService.getInstance();
        service.initConnection(uuid);
        return httpResponse;
    }

    /**
     * @param httpRequest
     * @param httpResponse
     * @param channelContext
     * @throws Exception
     * @author tanyaowu
     */
    @Override
    public void onAfterHandshaked(HttpRequest httpRequest, HttpResponse httpResponse, ChannelContext channelContext) throws Exception {
        int count = Tio.getAll(channelContext.tioConfig).getObj().size();
        String msg = "{name:'admin',message:'用户" + channelContext.getBsId() + " 上线了，共【" + count + "】人在线" + "'}";
        //用tio-websocket，服务器发送到客户端的Packet都是WsResponse
        //WsResponse wsResponse = WsResponse.fromText(msg, Const.CHARSET);
        //Tio.sendToAll(WebSocketServerStarter.getServerTioConfig(),wsResponse);
        log.info("onAfterHandshaked:{}",msg);
    }

    /**
     * 字节消息（binaryType = arraybuffer）过来后会走这个方法
     */
    @Override
    public Object onBytes(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
        String text = new String(bytes, "utf-8");
        log.info("收到byte消息:{},{}", bytes, text);
        ByteBuffer buffer = ByteBuffer.allocate(bytes.length);
        buffer.put(bytes);
        return buffer;
    }

    /**
     * 当客户端发close flag时，会走这个方法
     */
    @Override
    public Object onClose(WsRequest wsRequest, byte[] bytes, ChannelContext channelContext) throws Exception {
        Tio.remove(channelContext, "receive close flag");
        int count = Tio.getAll(channelContext.tioConfig).getObj().size();
        String msg = "{name:'admin',message:'用户" + channelContext.getBsId() + " 离线了，还有【" + count + "】人在线" + "'}";
        log.info("onClose:{}",msg);
        //WsResponse wsResponse = WsResponse.fromText(msg, Const.CHARSET);
        //Tio.sendToAll(WebSocketServerStarter.getServerTioConfig(),wsResponse);
        return null;
    }

    /**
     * 字符消息（binaryType = blob）过来后会走这个方法
     */
    @Override
    public Object onText(WsRequest wsRequest, String text, ChannelContext channelContext) throws Exception {
        WsSessionContext wsSessionContext = (WsSessionContext) channelContext.get();
        HttpRequest httpRequest = wsSessionContext.getHandshakeRequest();//获取websocket握手包
        log.info("握手包:{}" , httpRequest);
        log.info("收到ws消息:{}" , text);
        if (Objects.equals("心跳内容", text)) {
            return null;
        }
        TioWebShellService service = TioWebShellService.getInstance();
        service.recvHandle(text,channelContext.getBsId());
        return null;
    }
}